﻿using DLL.MSDM.Entity;
using DLL.Net.DB.Recorder.CRUD.Service;
using DLL.Net.MS.Models;
using DLL.NET.Commonly.Json;
using DLL.NET.Login.Account.Entity.DTO;
using DLL.NET.WEB.Static.ScanBar;
using DLL.NET50.DB.MS.AdviceAndDrug;
using DLL.NET50.DB.MS.AdviceAndDrug.ORM.Repository;
using DLL.NET50.DB.MS.AdviceAndDrug.ORM.Service;
using DLL.NET50.DB.MS.Entity;
using DLL.NET50.DB.MS.PIVASAndDicDrug.ORM;
using DLL.NET50.DB.PIVAS.Entitys.DTO;
using DLL.NET50.DB.PIVAS.ORM.Service;

using DLL.NET60.DB.MS.Entity.DTO;
using DLL.NET70.Infrastructure.EventAggregator;
using DLL.NET70.Infrastructure.Prism.EventAggregator;
using DLL.NetStandard.FlushRobot.MS.Entity.Param;
using DLL.Standard.Infrastructure.Entity;
using DLL.Standard.Infrastructure.Log;

using Prism.Events;
using Prism.Services.Dialogs;

using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace Module.AutoRun
{
    public class CGetValidBarParam
    {
        private int _BarCharCount = 20;   //条码个数

        public int BarCharCount
        {
            get { return _BarCharCount; }
            set
            {
                if (_BarCharCount != value)
                {
                    _BarCharCount = value;
                }
            }
        }

        private int _BarCharStartPos = 0;   //条码个数

        public int BarCharStartPos
        {
            get { return _BarCharStartPos; }
            set
            {
                if (_BarCharStartPos != value)
                {
                    _BarCharStartPos = value;
                }
            }
        }

        private int _EnableProcessBar = 0;

        public int EnableProcessBar
        {
            get { return _EnableProcessBar; }
            set
            {
                if (_EnableProcessBar != value)
                {
                    _EnableProcessBar = value;
                }
            }
        }//西林瓶夹抓启用标志位

        private int _ProcessBarMethord = 0;

        public int ProcessBarMethord
        {
            get { return _ProcessBarMethord; }
            set
            {
                if (_ProcessBarMethord != value)
                {
                    _ProcessBarMethord = value;
                }
            }
        }//西林瓶夹抓启用标志位

        private int _enableBatchDM = 0;

        public int enableBatchDM
        {
            get { return _enableBatchDM; }
            set { _enableBatchDM = value; }
        }

        private int _scanBarResultType = 0;//扫码返回状态种类，0，只有两种，1大于两种

        public int scanBarResultType
        {
            get { return _scanBarResultType; }
            set
            {
                if (_scanBarResultType != value)
                {
                    _scanBarResultType = value;
                }
            }
        }
    }

    public interface IScanBarBase
    {
        public int ConnectMode { get; set; }
        public int[] CanUsedLabelStation { get; set; }
        public int maxSolventCount { get; set; }
        public string ErrorInfo { get; set; }
        public int EnableJiFei { get; set; }
        public int reFlushModeIndex { get; set; }
        public string SelectedBatch { get; set; }
        public ISendLogMessage LogMsg { get; }

        public void ResetValidHadScanedBar();

        public void InitializeCurrentUsedDrug();
    }

    public class CScanBarBase : IScanBarBase
    {
        #region private variable

        private string[] _ValidHadScanedBar = new string[6] { "0", "0", "0", "0", "0", "0" };//用来存储已经扫描过的有效条码
        private Dictionary<string, string> _AllHadScanedBar = new Dictionary<string, string>();//用来存储已经扫描过的所有条码
        private string[] _currentUsedDrugsName = new string[6];
        private string[] _currentUsedSolventName = new string[6];

        private int _maxSolventCount = 6;
        private int _adviceStopID = 0;
        private int _ConnectMode = 1;
        private string _url = "http://localhost:8085/WebServiceCharge.asmx";
        public CWeb_ScanBar _webScanBar;

        #endregion private variable

        #region property

        public CGetValidBarParam ValidBarParam { get; set; } = new CGetValidBarParam();
        private string _errorInfo = "";

        public string ErrorInfo
        {
            get { return _errorInfo; }
            set
            {
                LogMessage(value);
                _errorInfo = value;
            }
        }

        public string[] ValidHadScanedBar
        {
            get { return _ValidHadScanedBar; }
            set { _ValidHadScanedBar = value; }
        }

        public Dictionary<string, string> AllHadScanedBar
        {
            get { return _AllHadScanedBar; }
            set { _AllHadScanedBar = value; }
        }

        public string[] currentUsedDrugsName
        {
            get { return _currentUsedDrugsName; }
            set { _currentUsedDrugsName = value; }
        }

        public string[] currentUsedSolventName
        {
            get { return _currentUsedSolventName; }
            set { _currentUsedSolventName = value; }
        }

        public int adviceStopID
        {
            get { return _adviceStopID; }
        }

        private string _scanedBar = "";

        public string ScanedBar
        {
            get { return _scanedBar; }
            set { _scanedBar = value; }
        }

        public int ConnectMode
        {
            get { return _ConnectMode; }
            set { _ConnectMode = value; }
        }

        private int _reFlushModeIndex = 1;

        public int reFlushModeIndex
        {
            get { return _reFlushModeIndex; }
            set { _reFlushModeIndex = value; }
        }

        private string _SelectedBatch = "0";

        public string SelectedBatch
        {
            get { return _SelectedBatch; }
            set { _SelectedBatch = value; }
        }

        private int _SelectedBatchIndex = 0;

        public int SelectedBatchIndex
        {
            get { return _SelectedBatchIndex; }
            set { _SelectedBatchIndex = value; }
        }

        private int _enableJiFei = 0;

        public int EnableJiFei
        {
            get { return _enableJiFei; }
            set { _enableJiFei = value; }
        }

        public int maxSolventCount
        {
            get { return _maxSolventCount; }
            set { _maxSolventCount = value; }
        }

        //这个变量用来标记哪个站可以使用
        private int[] _CanUsedLabelStation = new int[] { 1, 1, 1, 1, 1, 1 };

        public int[] CanUsedLabelStation
        {
            get { return _CanUsedLabelStation; }
            set { _CanUsedLabelStation = value; }
        }

        public ISendLogMessage LogMsg
        {
            get
            {
                return _logMsg;
            }
        }

        #endregion property

        private IEventAggregator _eventAggregator;

        private IAdviceRecordService _recorderService;

        public IAdviceRecordService RecorderService
        {
            get { return _recorderService; }
        }

        private IAdviceExecuteService _pivasAdviceService;

        public IAdviceExecuteService PivasAdviceService
        {
            get { return _pivasAdviceService; }
        }

        //private IMS_ProcessAdvice _szProcessAdvice;
        private adi_accountDTO _logAccount;

        private ISendLogMessage _logMsg;
        private IDialogService _dialogService;

        public CScanBarBase(IEventAggregator eventAggregator,
            IAdviceExecuteService pivasAdviceService,
            IAdviceRecordService recordService,
            ISendLogMessage sendLogMessage,
            adi_accountDTO logAccount,
            IDialogService dialogService)
        {
            _eventAggregator = eventAggregator;
            _pivasAdviceService = pivasAdviceService;
            _recorderService = recordService;
            _logAccount = logAccount;
            _logMsg = sendLogMessage;
            _webScanBar = new CWeb_ScanBar();
            _dialogService = dialogService;
        }

        #region event

        public void SendLogMessage(string _message, LogLevel logLevel = LogLevel.Debug)
        {
            CLogMessage logMessage = new CLogMessage();
            logMessage.Message = _message;
            logMessage.Level = (int)logLevel;
            _eventAggregator.GetEvent<CLogMessageEvent>().Publish(logMessage);
        }

        public void LogMessage(string _message, LogLevel logLevel = LogLevel.Debug)
        {
            _logMsg.Publish(_message, logLevel);
        }

        public virtual int ProcessScanBar(string scanBar)
        {
            return 1;
        }

        public virtual void SendAdviceStopMessage()
        {
        }

        #endregion event

        /*
         try
            {
            }
            catch (Exception e)
            {
                LogMsg.Warn(""+e.Message);
                return 0;
            }
         */

        //条码处理功能，用来解决，读取到的瓶贴号与扫描到的瓶贴号不一致
        public virtual int GetValidBar(string bar, ref string adviceNo)
        {
            try
            {
                if (1 == ValidBarParam.EnableProcessBar)
                {
                    if (0 == ValidBarParam.ProcessBarMethord)
                    {
                        //处理条码的方式1：
                        string[] bars = bar.Split("|");
                        if (bars.Count() == 2)
                        {
                            adviceNo = bars[1];
                        }
                        else
                        {
                            adviceNo = bar;
                            LogMessage("条码处理出现异常！" + bar);
                            return 0;
                        }
                    }
                    else if (1 == ValidBarParam.ProcessBarMethord)
                    {
                        string[] bars = bar.Split("&");
                        if (bars.Count() > 0)
                        {
                            adviceNo = bars[0];
                        }
                        else
                        {
                            adviceNo = bar;
                            LogMessage("条码处理出现异常！" + bar);
                            return 0;
                        }
                    }
                    else if (2 == ValidBarParam.ProcessBarMethord)
                    {
                        if (bar.Length >= (ValidBarParam.BarCharStartPos + ValidBarParam.BarCharCount))
                        {
                            adviceNo = bar.Substring(ValidBarParam.BarCharStartPos, ValidBarParam.BarCharCount);
                        }
                        else
                        {
                            LogMessage("条码截取参数设置异常！" + bar);
                            adviceNo = bar;
                            return 0;
                        }
                    }
                    else
                    {
                        adviceNo = bar;
                    }
                }
                else
                {
                    adviceNo = bar;
                }
            }
            catch (Exception e)
            {
                LogMessage("从扫码中获取医嘱编码出现异常：" + e.Message, LogLevel.Warning);
                return 0;
            }

            return 1;
        }

        //判断有没有停医嘱
        public virtual int AdviceIsNotStop(string barCode, string userCode)
        {
            try
            {
                if (_enableJiFei == 1)
                {
                    int ret = 0;
                    ret = _webScanBar.PIVASaveStatus(barCode, userCode);
                    if (-1 == ret)
                    {
                        ErrorInfo = ("连接服务器出现异常！");
                        _logMsg.Warn(ErrorInfo);
                        return -1;
                    }
                    else
                    {
                        if (0 == ValidBarParam.scanBarResultType)
                        {
                            //只有两种返回结果
                            if (0 == ret)
                            {
                                ErrorInfo = ("停医嘱");
                                _adviceStopID++;
                                SendAdviceStopMessage();
                                return 0;
                            }
                            else if (1 == ret)
                            {
                                //扫码正常
                                return 1;
                            }
                        }
                        else
                        {
                            //有多种返回结果，
                            //其他状态，不可以配药
                            //其他状态，没有停医嘱，但是不可以配药
                            //根据状态码，获取状态信息
                            Rootobject appsetting = CWRJson.ReadRootobject<Rootobject>();
                            List<Scanbarresult> results = new List<Scanbarresult>(appsetting.ScanBarResults);
                            Scanbarresult result = results.Where(w => w.Value == ret).FirstOrDefault();
                            if (result != null)
                            {
                                ErrorInfo = result.State;
                                if (0 == result.CanFlush)
                                {
                                    //停医嘱
                                    ErrorInfo = ("停医嘱");
                                    _adviceStopID++;
                                    SendAdviceStopMessage();
                                    return 0;
                                }
                                else if (1 == result.CanFlush)
                                {
                                    return 1;
                                }
                                else if (2 == result.CanFlush)
                                {
                                    //询问提示，是否可以配
                                    ButtonResult mbr = ButtonResult.Yes;//
                                    string str = result.State;
                                    Application.Current.Dispatcher.Invoke(
                                    (Action)delegate ()
                                    {
                                        _dialogService.ShowDialog("AlertDialog", new DialogParameters($"message={str + "，是否可以配药？"}"), r =>
                                        {
                                            mbr = r.Result;
                                        });
                                    });
                                    if (mbr == ButtonResult.Yes)
                                    {
                                        //可以配
                                        return 1;
                                    }
                                    else
                                    {
                                        //不可以配
                                        return 0;
                                    }
                                }
                                else
                                {
                                    //没有停医嘱，也不可以配，也不需要询问，只显示不能配的 原因
                                    _logMsg.Warn(ErrorInfo);
                                    return 0;
                                }
                            }
                            else
                            {
                                ErrorInfo = "返回的状态值没有对应的状态信息，请到appsetting.json里面设置";
                                _logMsg.Warn(ErrorInfo);
                                return 0;
                            }
                        }
                    }
                    if (0 == ret)
                    {
                        ErrorInfo = ("停医嘱");
                        _adviceStopID++;
                        SendAdviceStopMessage();
                        return 0;
                    }
                    else if (1 == ret)
                    {
                        //扫码正常
                        return 1;
                    }
                    else if (ret > 1)
                    {
                        //其他状态，不可以配药
                        //其他状态，没有停医嘱，但是不可以配药
                        //根据状态码，获取状态信息
                        Rootobject appsetting = CWRJson.ReadRootobject<Rootobject>();

                        List<Scanbarresult> results = new List<Scanbarresult>(appsetting.ScanBarResults);
                        Scanbarresult result = results.Where(w => w.Value == ret).FirstOrDefault();
                        if (result != null)
                        {
                            ErrorInfo = result.State;
                            _logMsg.Warn(ErrorInfo);
                            return 0;
                        }
                        else
                        {
                            ErrorInfo = "返回的状态值没有对应的状态信息，请到appsetting.json里面设置";
                            _logMsg.Warn(ErrorInfo);
                        }
                        return 0;
                    }
                    else
                    {
                        ErrorInfo = ("连接服务器出现异常！");
                        _logMsg.Warn(ErrorInfo);
                        return -1;
                    }
                }
            }
            catch (Exception e)
            {
                _logMsg.Warn("判断医嘱是否停医嘱出现异常：" + e.Message);
            }

            return 1;
        }

        //判断条码是否有效
        public int TheBarCanFlush(string scanBar)
        {
            try
            {
                //判断该医嘱是不是已经配过了
                int ret = EnableReflush(scanBar);
                if (ret == 0)
                {
                    return 0;
                }
                //判断有没有启用分批配药
                ret = EnableBatchDM(scanBar);
                if (ret == 0)
                {
                    return 0;
                }
                //首先判断本地是否存在该医嘱
                ret = LocalHadThisAdvice(scanBar);
                if (ret == 0)
                {
                    return 0;
                }
            }
            catch (Exception e)
            {
                _logMsg.Warn("判断是否可以配药出现异常：" + e.Message);
                return 0;
            }

            return 1;
        }

        //本地数据库，是否存在该医嘱
        public virtual int LocalHadThisAdvice(string scanBar)
        {
            return 0;
        }

        //是否启用了重配
        public int EnableReflush(string scanBar)
        {
            try
            {
                if (_logAccount.MAuthority < 3)
                {
                    int hadScaned = _recorderService.HadFlush(scanBar);
                    if (1 == hadScaned)
                    {
                        if (0 == reFlushModeIndex)
                        {
                            //不允许重配
                            ErrorInfo = ("该医嘱已经配过，不允许重配！");
                            return 0;
                        }
                        else
                        {
                            //允许重配
                            reFlushModeIndex = 0;
                            return 1;
                        }
                    }
                    else
                    {
                        //医嘱不存在
                        return 1;
                    }
                }
            }
            catch (Exception e)
            {
                _logMsg.Warn("重配处理出现异常：" + e.Message);
                return 0;
            }

            return 1;
        }

        //启用分批配药
        public virtual int EnableBatchDM(string scanBar)
        {
            try
            {
                if (ValidBarParam.enableBatchDM == 1)
                {
                    List<DTO_adi_advice_execute> advices = _pivasAdviceService.GetAdviceExcuteByBottleNum(scanBar);
                    if (advices.Count() > 0)
                    {
                        if (advices[0].BATCH_CODE != (SelectedBatch))
                        {
                            LogMessage("启用分批配药:医嘱批次与设置的批次不同，不允许配药！");
                            ErrorInfo = ("批次不同,不允许配药！");
                            return 0;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                _logMsg.Warn("处理分批配药出现异常：" + e.Message);
                return 0;
            }

            return 1;
        }

        //判断是否要换针
        public virtual int NeedChangeInjector(List<string> drugCodes)
        {
            return 1;
        }

        //是否要设置药品的属性
        public virtual int SetDrugProperty(string scanBar)
        {
            return 1;
        }

        //换针时：清空每个站记录的正在配的药，和正在使用的溶媒
        public virtual void InitializeCurrentUsedDrug()
        {
            for (int i = 0; i < 6; i++)
            {
                currentUsedDrugsName[i] = "";
                currentUsedSolventName[i] = "";
            }
            //sP_ScanBar = new CSP_ScanBar();
        }

        //初始化，扫过的条码记录信息，和每个站记录的有效条码信息
        public virtual void InitializeVariable()
        {
            LogMessage("清空医嘱！");
            InitializeValidScanBar();
            InitializeCurrentUsedDrug();
            _AllHadScanedBar = new Dictionary<string, string>();//用来存储已经扫描过的所有条码
            AllHadScanedBar.Clear();
        }

        //初始化可以使用的瓶贴站位
        public void InitializeValidScanBar()
        {
            for (int i = 0; i < 6; i++)
            {
                if (0 == CanUsedLabelStation[i])
                {
                    //这个占位没有启用
                    ValidHadScanedBar[i] = "0";
                }
                else
                {
                    ValidHadScanedBar[1] = "1";
                }
            }
        }

        //获取还没有被使用的瓶贴站台号
        public int GetNotUsedStationID()
        {
            for (int i = 0; i < ValidHadScanedBar.Length; i++)
            {
                if ("1" == (ValidHadScanedBar[i]))
                {
                    //这个占位没有启用
                    return i;
                }
            }
            return -1;//说明所有的站都已经被使用
        }

        public virtual void ResetValidHadScanedBar()
        {
            for (int i = 0; i < ValidHadScanedBar.Length; i++)
            {
                ValidHadScanedBar[i] = CanUsedLabelStation[i].ToString();
            }
        }
    }
}